#pragma once

#include <GL/glew.h>
#include <iostream>
#include <vector>

namespace cagd
{
    class TriangularFace
    {
        // output to stream
        friend std::ostream& operator <<(std::ostream& lhs, const TriangularFace& rhs);

        // input from stream
        friend std::istream& operator >>(std::istream& lhs, TriangularFace& rhs);

    private:
        std::vector<GLuint> _node;

    public:

        // default constructor
        TriangularFace()
        {
            _node.resize(3, 0);
        }

        // copy constructor
        TriangularFace(const TriangularFace& face)
        {
            _node.resize(3, 0);
            _node[0] = face[0];
            _node[1] = face[1];
            _node[2] = face[2];
        }

        // assignment operator
        TriangularFace& operator =(const TriangularFace& rhs)
        {
            if (this == &rhs)
                return *this;

            _node.resize(3, 0);
            _node[0] = rhs[0];
            _node[1] = rhs[1];
            _node[2] = rhs[2];
            return *this;
        }

        // get/set
        GLuint operator [](GLint i) const
        {
            if (i < 0)
                return _node[0];
            if (i > 2)
                return _node[2];
            return _node[i];
        }
        GLuint& operator [](GLint i)
        {
            if (i < 0)
                return _node[0];
            if (i > 2)
                return _node[2];
            return _node[i];
        }
    };

    inline std::ostream& operator <<(std::ostream& lhs, const TriangularFace& rhs)
    {
        GLuint n = rhs._node.size();
        lhs << n;
        for (std::vector<GLuint>::const_iterator it = rhs._node.begin(); it != rhs._node.end(); it++)
            lhs << " " << *it;
        return lhs;
    }

    inline std::istream& operator >>(std::istream& lhs, TriangularFace& rhs)
    {
        GLuint n;
        lhs >> n;
        rhs._node.resize(n);
        for (GLuint i = 0; i < n; i++)
            lhs >> rhs._node[i];
        return lhs;
    }
}
